#pragma once

#include <string>
#include <ostream>
#include <iostream>

#include "topdbs_base_session.hpp"

#include "mysql_common.hpp"
#include "mysql_connection.hpp"

namespace topdbs
{
	class mysql_session 
		: public topdbs_base_session
	{	
	protected:
		mysql_connection* m_pConnection;	
		MyStmtment*  m_pStmt;
		MyStream* m_pStream;	
		MyCursor* m_pCursor;

		std::map<int,string> m_xBind;
	public:	
		mysql_session();
		mysql_session(mysql_connection* pConnection);
		virtual ~mysql_session();

		//! reset the current command all info.
		virtual void Reset() override;
		//! Validates and prepares the current command for execution.
		virtual int  Prepare() override;
		//! Executes the current command.
		virtual int  Execute() override; 
		virtual int  Execute(const char* sSQL,...) override; 	
		virtual int  ExecuteV(const string& sSQL,va_list vaList) override;
		virtual int  ExecuteFetch(const string& sSQL) override;
		virtual bool FetchNext() override;
		virtual bool FetchCursorNext(uint16_t nFetchSize = TOPDBS_DEFAULT_FETCH_SIZE) override;
		//! Binding the command parameter specified by its position
		virtual int  BindParams(const uint16_t paramno,const DBSValue& value) override;
		virtual int  BindParams(const uint16_t paramno,const string& value) override;
		virtual int  BindParams(const uint16_t paramno,const int     value) override;
		virtual int  BindParams(const uint16_t paramno,const long    value) override;
		virtual int  BindParams(const uint16_t paramno,const float   value) override;
		virtual int  BindParams(const uint16_t paramno,const double  value) override;

	private:
		int ExecuteUpdate(const std::string& sSQL);
		int ExecuteQuery(const std::string& sSQL);
		int ExecuteQuery_Row(const std::string& sSQL);
		int Prepare_cursor(MYSQL* connection_ptr);
		int Prepare_stmt(MYSQL* connection_ptr);
		int ExecuteStmt();
		int ExecuteCursor();
		int ExecuteStream();
		int BindCursorParam(int paramno,int valueType,void* value);
	};
}